import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix


def ShowHeatMap(df) :
    # Построение тепловой карты с использованием seaborn
    plt.figure(figsize=(10, 8))
    sns.heatmap(df.corr(), annot=True, cmap='coolwarm', fmt=".3f", vmin=-1, vmax=1)
    plt.title('Тепловая карта корреляции')
    plt.show()


def DelCorrHand(df)->pd.DataFrame : 
    sym = input("Желаете удалить столбец?\n")
    while (sym == 'y') :
        col=int(input("Какой столбец удалить?\n"))

        df = df.drop(df.columns[col-1], axis=1)

        # Построение тепловой карты с использованием seaborn
        plt.figure(figsize=(10, 8))
        sns.heatmap(df.corr(), annot=True, cmap='coolwarm', fmt=".3f", vmin=-1, vmax=1)
        plt.title('Тепловая карта корреляции')
        plt.show()

        sym = input("Желаете удалить столбец?\n")
    return df


def CleanData(df) -> pd.DataFrame :
    """
    Очищает данные:
    1. замена пропущенных значений
    2. замена названий
    3. удаление дубликатов
    """


    # удаление столбцов с пропущенным значением(данные категориальны, заместить нет возможности) 
    df = df[~df.apply(lambda row: any(row == '?'), axis=1)]

    # удаление столбцов с одинаковыми значениями
    df = df.loc[:, df.nunique() > 1]
    return df



# Загрузка данных из CSV файла
df = pd.read_csv('agaricus-lepiota.data')
print("Прочитано:\n", df, "\n")

df = CleanData(df)
print("После очистки:\n", df, "\n")

df = df.apply(lambda col: pd.factorize(col)[0])
print("После замен:\n", df, "\n")


ShowHeatMap(df)

threshold=float(input("Удалить столбцы с коэффициентом корреляции больше:"))

# Нахождение столбцов, которые коррелируют между собой
columns_to_drop = set()
for i in range(len(df.columns)):
    for j in range(i):
        if abs(df.corr().iloc[i, j]) > threshold:  # Устанавливаем порог корреляции
            colname = df.columns[i]
            columns_to_drop.add(colname)

# Удаление столбцов
df = df.drop(columns=columns_to_drop)

ShowHeatMap(df)


#df = DelCorrHand(df)



# Разделение на признаки (X) и метки (y)
X = df.iloc[:, 1:].values
y = df.iloc[:, 0].values

# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Создаем и обучаем многослойный персептрон классификатор
mlp_classifier = MLPClassifier(hidden_layer_sizes=(len(X[0]), len(X[0]), len(X[0])), max_iter=len(X_test), random_state=42, solver="adam")
mlp_classifier.fit(X_train, y_train)

# Предсказываем значения для тестовой выборки
y_pred = mlp_classifier.predict(X_test)

# Оцениваем качество модели
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy on Test Data: {accuracy}")

# Создаем матрицу ошибок
conf_matrix = confusion_matrix(y_test, y_pred)
print(conf_matrix)

# Извлекаем значения из матрицы ошибок
tn, fp, fn, tp = conf_matrix.ravel()


# Выводим результаты
print(f"True Negatives: {tn}")
print(f"False Positives: {fp}")
print(f"False Negatives: {fn}")
print(f"True Positives: {tp}")